//David Wasser
//February 18, 2009
//Software Design, Period 6
//Ultimate Frisbee

/* DefStack is the Strategy that controls the routines
 * in an defensive stack (DefStack) strategy in which the players
 * are each assigned a mark to guard that they follow around the
 * field.
 */

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Iterator;
import java.util.Set;

import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
public class DefStack extends DefStrategy{
	Object[] catcher;
	
	/** Creates a new DefStack for the input Team on
	 ** the input Field
	 **/
	public DefStack(Team team, Field field){
		super(team, field);
		double temp1 = Field.bounds.y/14;
		Point3d temp2;
		if(team.endZone == Team.RIGHT)
			temp2 = new Point3d(Field.GOAL, Field.bounds.y/4, 0);
		else
			temp2 = new Point3d(Field.bounds.x-Field.GOAL, Field.bounds.y/4, 0);
		for(int i=0; i<7; i++){
			routes.put(i, new DefStackRoutine(team.players.get(i), (Point3d) temp2.clone(), null, this));
			team.players.get(i).position = (Point3d) temp2.clone();
			team.players.get(i).velocity = new Vector3d((team.endZone == Team.RIGHT?1:-1),0,0);
			temp2.y += temp1;
		}//End for
		if(field == null)
			starting = true;
	}//End DefStack()
	
	/** Creates an DefStack with the given Players, Team, and Field
	 **/
	public DefStack(Set<Player> players, Team team, Field field){
		super(team, field);
		Iterator<Player> it = players.iterator();
		Player temp1;
		Player temp3;
		ArrayList<Player> tempList1;
		ArrayList<Player> tempList2 = new ArrayList<Player>();
		Iterator<Player> it2;
		for(int i=0; it.hasNext(); i++){
			temp1 = it.next();
			tempList1 = field.playersByClosestTo(temp1.position, team.getOtherTeam().getPlayers());
			it2 = tempList1.iterator();
			while(it2.hasNext()){
				temp3 = it2.next();
				if(!tempList2.contains(temp3)){
					tempList2.add(temp3);
					routes.put(i, new DefStackRoutine(temp1, temp1.position, temp3, this));
					break;
				}//End if
			}//End while
		}//End while
		
	}//End OffStack
	
	/** This is called whenever the disc is either caught
	 ** or thrown with the catcher/thrower as the input.
	 ** It moves a Player to catch the disc.
	 **/
	public void discChange(Player player){
		if(starting)
			starting = false;
		if(!field.disc.isHeld()){
			catcher = getClosestToDisc(field.disc, team.getPlayers(), field.dt);
			((DefStackRoutine)((Player)catcher[0]).routine).setCatching((Point3d)catcher[1]);
		}//End if
	}//End discChange
	
	/** Sets the field in DefStack and all its routines
	 ** and gives each of the routines a mark to guard.
	 **/
	public void setField(Field gameField){
		field = gameField;
		routes.isEmpty();
		Iterator<Integer> it = routes.keySet().iterator();
		while(it.hasNext())
			routes.get(it.next()).setField(gameField);
		Player temp3;
		ArrayList<Player> tempList1;
		ArrayList<Player> tempList2 = new ArrayList<Player>();
		Iterator<Player> it2;
		for(int i=0; i<7; i++){
			tempList1 = field.playersByClosestTo(team.players.get(i).position, team.getOtherTeam().getPlayers());
			it2 = tempList1.iterator();
			while(it2.hasNext()){
				temp3 = it2.next();
				if(!tempList2.contains(temp3)){
					tempList2.add(temp3);
					routes.put(i, new DefStackRoutine(team.players.get(i), team.players.get(i).position, temp3, this));
					break;
				}//End if
			}//End while
		}//End for
	}//End setField()
}//End DefStack